<?php

namespace App\Jobs;

use App\Exceptions\ApiException;
use App\Models\ActionLog;
use App\Models\PartCompany;
use App\Models\Project;
use App\Models\ProjectClassify;
use App\Services\CommonService;
use App\Services\SystemConfigService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Storage;
use OSS\OssClient;

class BatchUpPdf implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $userId;
    protected $maxSize;
    protected $accessKeyId;
    protected $accessKeySecret;
    protected $endpoint;
    protected $bucket;
    protected $ossClient;
    protected $partCompanyId;
    protected $projectClassifyId;
    protected $bookTitleId;
    protected $tmpFileInfo;

    public function __construct($partCompanyId, $projectClassifyId, $bookTitleId, $tmpFileInfo)
    {
        $config = SystemConfigService::getInfo(); //获取系统配置 (项目要求把配置文件存放到数据库，而不是 .env文件)

        $this->maxSize           = 2000 * 1024 * 1024;
        $this->bucket            = $config['bucket'];
        $this->endpoint          = $config['endpoint'];
        $this->accessKeyId       = $config['oss_access_key'];
        $this->accessKeySecret   = $config['oss_access_secret'];
        $this->ossClient         = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
        $this->partCompanyId     = $partCompanyId;
        $this->projectClassifyId = $projectClassifyId;
        $this->bookTitleId       = $bookTitleId;
        $this->tmpFileInfo       = $tmpFileInfo;
    }

    /**
     * Execute the job.
     *
     * @throws ApiException
     * @author: lxk
     * @date: 2024-11-22 14:48
     */
    public function handle()
    {
        $option = ['Content-Disposition' => 'inline',];
        $result = $this->ossClient->uploadFile($this->bucket, $this->tmpFileInfo['path_name'], $this->tmpFileInfo['tmp_file'], $option); //OSS上传并获取返回结果
        $ossUrl = $result['info']['url'];
        if (!str_contains($ossUrl, 'https')) { //如果不是https
            $ossUrl = str_replace('http', 'https', $ossUrl); //把http转化为https
        }
        $uploadResult = $this->tmpFileInfo;
        $uploadResult['file'] = $ossUrl;
        $this->addNewPdf($this->partCompanyId, $this->projectClassifyId, $uploadResult);
    }

    /**
     * 分析PDF文件名，并写入数据
     *
     * @param $partCompanyId
     * @param $projectClassifyId
     * @param $uploadResult
     * @return bool
     * @throws ApiException
     * @author: lxk
     * @date: 2024-12-18 14:07
     */
    public function addNewPdf($partCompanyId, $projectClassifyId, $uploadResult)
    {
        $originName = $uploadResult['origin_name'];
        $pos        = strrpos($originName, '-');     //最后'-'出现的位置
        $serialNo   = substr($originName, $pos + 1); //序号
        $bookCatalogInstance = CommonService::getBookCatalogInstance($partCompanyId, $projectClassifyId);
        $bookCatalog = $bookCatalogInstance
            ->where('book_title_id', $this->bookTitleId)
            ->where('serial_no', $serialNo)
            ->first();

        if (!empty($bookCatalog)) {
            $bookCatalog->file_url = 1; //标记为有pdf
            $bookCatalog->save();
            //增加一条数据
            $bookCatalogPdfInstance                  = CommonService::getBookCatalogPdfInstance($partCompanyId, $projectClassifyId);
            $bookCatalogPdfInstance->book_title_id   = $this->bookTitleId;
            $bookCatalogPdfInstance->book_catalog_id = $bookCatalog->id;
            $bookCatalogPdfInstance->file_url        = $uploadResult['file'];
            $bookCatalogPdfInstance->file_size       = $uploadResult['file_size'];
            $bookCatalogPdfInstance->origin_name     = $originName;

            $tmpFile = $uploadResult['tmp_file'];
            Storage::delete(substr($tmpFile, strpos($tmpFile, 'public'))); //上传之后，清除临时文件

            $this->addBatchUpPdfLog($partCompanyId, $projectClassifyId);

            return $bookCatalogPdfInstance->save();
        }

        return true;
    }

    /**
     * 写入操作日记，由于原来封装的日志方法使用了好几个助手函数，助手函数又无法直接在队列使用，所以单独在这里写个
     */
    public function addBatchUpPdfLog($partCompanyId, $projectClassifyId)
    {
        $key = get_user_key("import_pdf_in_title:$projectClassifyId");
        if ($actionLogId = redis()->get($key)) {
            ActionLog::query()->where('id', $actionLogId)->increment('count');
        } else {
            $partCompany  = PartCompany::query()->find($partCompanyId);
            $projectName  = Project::query()->where('id', $partCompany->project_id)->value('title');
            $classifyName = ProjectClassify::query()->where('id', $projectClassifyId)->value('title'); //项目分类

            $adminLog               = new ActionLog();
            $adminLog->user_id      = $this->tmpFileInfo['user_id'];
            $adminLog->company_id   = $this->tmpFileInfo['company_id'];
            $adminLog->user_name    = $this->tmpFileInfo['user_name'];
            $adminLog->company_name = $this->tmpFileInfo['company_name'];
            $adminLog->role_name    = $this->tmpFileInfo['role_name'];
            $adminLog->event        = "案卷批量导入PDF,单位工程id={$projectClassifyId}";
            $adminLog->detail       = "{$projectName}/{$partCompany->title}/{$classifyName}【分表后缀:{$partCompanyId}_{$projectClassifyId}";

            $result = CommonService::getRequestAddress();
            $adminLog->action_ip = $result['ip']; //记录ip
            $adminLog->address   = $result['address']; //保留省市
            $adminLog->save();
            redis()->setex($key, 43200, $adminLog->id); //12小时内同一单位工程上传PDF，增加数量，不增加记录
        }

    }

}
